﻿using PBO.Data;
using PBO.Data.Util;
using PBO.Game.Img;
using System;
using System.Collections.Generic;
using System.Linq;

namespace PBO.Game.BattleClass
{
    public partial class Pokemon
    {
        //private List<Move> SelectedMoves = Enumerable.Repeat<Move>(null, 4).ToList();
        private Move[] mSelMoves;

        public IEnumerable<Move> GetSelMoves()
        {
            for (int i = 0; i < 4; i++)
            {
                var move = GetSelMove(i + 1);
                if (move != null) yield return move;
            }
        }

        public Move GetSelMove(int index)
        {
            if (BattleState.TempMoves[index - 1] != null)
            {
                return BattleState.TempMoves[index - 1];
            }
            if (BattleState.transfrom)
                return null;
            return mSelMoves[index - 1];
        }

        public int GetSelMoveId(int index)
        {
            var move = GetSelMove(index);
            return move == null ? 0 : move.Data.Id;
        }

        public bool HaveMove(int id)
        {
            return this.GetSelMoves().Any(m => m.Data.Id == id);
        }

        public Move SetMove(int index, int mid, int ppUp)
        {
            if (0 < index && index < 5)
            {
                var move = new Move(mid, this, ppUp);
                mSelMoves[index - 1] = move;
                UpdateMove(move);
                return move;
            }
            return null;
        }

        public void SetTempMove(int index, Move moveValue)
        {
            if (0 < index && index < 5)
            {
                BattleState.TempMoves[index - 1] = moveValue;
                if (moveValue != null)
                    UpdateMove(moveValue);
            }
        }

        public void UpdateMove(Move moveValue)
        {
            if (MyTeam != null)
            {
                if (moveValue.Data.AddEffect2 == MoveAdditionalEffect.觉醒力量)
                {
                    moveValue.SetType(this.Iv.GetHiddenType());
                    moveValue.SetPower(this.Iv.GetHiddenPower());
                }
                else if (moveValue.Data.AddEffect2 == MoveAdditionalEffect.制裁飞石)
                {
                    if (GetItem(true).IsPlate())
                    {
                        moveValue.SetType((BattleType)((int)GetItem() - 63));
                    }
                    else
                    {
                        moveValue.SetType(BattleType.Normal);
                    }
                }
                else if (moveValue.Data.AddEffect2 == MoveAdditionalEffect.自然恩惠)
                {
                    if (GetItem(true).IsBerry())
                    {
                        moveValue.SetPower(ImageHelper.GetNaturalGiftPower((int)GetItem(true)));
                        moveValue.SetType(ImageHelper.GetNaturalGiftType((int)GetItem(true)));
                    }
                    else
                    {
                        moveValue.SetType(BattleType.Normal);
                        moveValue.SetPower(0);
                    }
                }
                else if (moveValue.Data.Effect == MoveEffect.诅咒)
                {
                    moveValue.UpdateCourse(this);
                }
            }
        }

        public bool CanUseMove(int index, bool addLog = false)
        {
            if (!addLog && BattleState.torment && lastMoveIndex == index && index != Battle.StruggleIndex)
            {
                return false;
            }
            if (BattleState.taunt && GetSelMove(index).Data.Category == MoveCategory.变化)
            {
                if (addLog)
                {
                    MyTeam.log.AppendMsg("Taunt", this.GetNameString(), GetSelMove(index).Data.Name);
                    //MyTeam.log.AddText(GetNameString() + "被挑拨不能使用" + GetSelMove(index).Name);
                }
                return false;
            }
            if (BattleState.DisableIndex == index)
            {
                if (addLog)
                {
                    MyTeam.log.AppendMsg("Disable", this.GetNameString(), GetSelMove(index).Data.Name);
                    //MyTeam.log.AddText(GetNameString() + "无法使用" + GetSelMove(index).Name);
                }
                return false;
            }
            foreach (Pokemon pm in MyTeam.Group.Opponent.SelectedPokemon)
            {
                if (pm.BattleState.imprison && pm.HaveMove(GetSelMoveId(index)))
                {
                    if (addLog)
                    {
                        MyTeam.log.AppendMsg("Imprison", this.GetNameString(), GetSelMove(index).Data.Name);
                        //MyTeam.log.AddText(GetNameString() + "被封印无法使用" + GetSelMove(index).Name);
                    }
                    return false;
                }
            }
            return true;
        }

        public bool NoMoveCanUse()
        {
            if ((BattleState.encore || this.UsedItem.IsChoiceItem()) && lastMoveIndex == Battle.StruggleIndex)
                return true;
            bool[] canUse = new bool[4] { true, true, true, true };


            for (int i = 1; i <= 4; i++)
            {
                if (GetSelMove(i) == null) { canUse[i - 1] = false; continue; }
                if (GetSelMove(i).PP == 0) { canUse[i - 1] = false; continue; }
                if ((BattleState.encore || this.UsedItem.IsChoiceItem()) && (lastMoveIndex != i || GetSelMove(i).PP == 0))
                {
                    canUse[i - 1] = false;
                    continue;
                }
                if (!CanUseMove(i)) { canUse[i - 1] = false; continue; }
            }
            for (int i = 0; i < 4; i++)
            {
                if (canUse[i]) return false;
            }
            return true;
        }

        public bool CanChooseMove
        {
            get
            {
                return !(BattleState.Hide || BattleState.bide || BattleState.nextTurnCantMove || BattleState.CrazyAttack || BattleState.prepare);
                //if (BattleState.Hide || BattleState.bide || BattleState.nextTurnCantMove || BattleState.CrazyAttack || BattleState.prepare)
                //{
                //    return false;
                //}
                //return true;
            }
        }

        public bool LastMoveIsValid
        {
            get { return IsValidMoveIndex(lastMoveIndex); }
        }

        public Move LastMove
        {
            get
            {
                return LastMoveIsValid ? GetSelMove(lastMoveIndex) : null;
            }
        }

        public static bool IsValidMoveIndex(int moveIndex)
        {

            return moveIndex != 0 && moveIndex != Battle.StruggleIndex;
        }
    }
}
